﻿// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.ComponentModel.Composition.ReflectionModel;
using System.Globalization;
using System.Reflection;
using Microsoft.Internal;

namespace System.ComponentModel.Composition.AttributedModel
{
    internal class AttributedMemberExportDefinition : ExportDefinition, ICompositionElement
    {
        private readonly string _contractName;
        private readonly IDictionary<string, object> _metadata;
        private readonly ReflectionMember _member;
        private readonly AttributedComposablePartDefinition _definition;

        public AttributedMemberExportDefinition(AttributedComposablePartDefinition definition, string contractName, MemberInfo member)
        {
            Assumes.NotNull(contractName, member);

            this._definition = definition;
            this._contractName = contractName;
            this._member = member.ToReflectionMember();

            // TODO: For now ignore any issues coming from this call they should 
            // end up in the list of discovery issues, when we do the discovery work
            IDictionary<string, object> metadata;
            member.TryExportMetadataForMember(out metadata);

            // Add the creation policy the export metadata if it exists on the part definition metadata
            if (this._definition != null && this._definition.Metadata != null &&
                this._definition.Metadata.ContainsKey(CompositionServices.PartCreationPolicyMetadataName))
            {
                metadata[CompositionServices.PartCreationPolicyMetadataName] =
                    this._definition.Metadata[CompositionServices.PartCreationPolicyMetadataName];
            }

            this._metadata = metadata.AsReadOnly();
        }

        public override string ContractName
        {
            get { return this._contractName; }
        }

        public ReflectionMember Member
        {
            get { return _member; }
        }

        public AttributedComposablePartDefinition Definition
        {
            get { return _definition; }
        }

        public override IDictionary<string, object> Metadata
        {
            get { return this._metadata; }
        }

        string ICompositionElement.DisplayName
        {
            get { return GetDisplayName(); }
        }

        ICompositionElement ICompositionElement.Origin
        {
            get { return _definition; }
        }

        public override string ToString()
        {
            return GetDisplayName();
        }

        public ExportingMember ToExportingMember()
        {
            return new ExportingMember(this, _member);
        }

        private string GetDisplayName()
        {
            return string.Format(CultureInfo.CurrentCulture,
                   "{0} (ContractName=\"{1}\")",    // NOLOC
                   this._member.DisplayName,
                   this.ContractName);
        }
    }
}
